<!-- frontend/src/components/RegulationPanel.vue -->
<template>
  <div class="regulation-panel">
    <div class="panel-header">
      <h3>🔒 智能合约安全审计</h3>
      <p class="panel-subtitle">上传Solidity合约代码进行安全分析</p>
    </div>
    
    <div class="panel-content">
      <!-- 左侧：代码输入区域 -->
      <div class="left-section">
        <!-- 代码上传区域 -->
        <div class="code-upload-section">
          <h4>📝 合约代码输入</h4>
          <div class="code-input-area">
            <textarea 
              v-model="contractCode" 
              placeholder="请粘贴您的Solidity智能合约代码..."
              rows="12"
              class="code-textarea"
            ></textarea>
          </div>
          
          <!-- 快速示例按钮 -->
          <div class="example-buttons">
            <button class="btn secondary" @click="loadVulnerableExample">
              加载漏洞示例
            </button>
            <button class="btn secondary" @click="loadSafeExample">
              加载安全示例
            </button>
          </div>
        </div>
        
        <!-- 审计参数设置 -->
        <div class="audit-params">
          <h5>审计参数</h5>
          <div class="param-row">
            <label>检测深度: {{ auditDepth }}</label>
            <input type="range" v-model="auditDepth" min="1" max="5" step="1" class="slider">
          </div>
          <div class="param-row">
            <label>检测模式: {{ auditMode }}</label>
            <select v-model="auditMode" class="mode-select">
              <option value="standard">标准模式</option>
              <option value="strict">严格模式</option>
              <option value="comprehensive">全面模式</option>
            </select>
          </div>
        </div>
        
        <!-- 操作按钮 -->
        <div class="action-buttons">
          <button 
            class="btn primary audit-btn" 
            @click="startAudit" 
            :disabled="!contractCode.trim() || auditing"
          >
            {{ auditing ? '审计中...' : '🔍 开始安全审计' }}
          </button>
          <button class="btn secondary" @click="clearCode">清空代码</button>
        </div>
      </div>
      
      <!-- 右侧：审计结果展示 -->
      <div class="right-section">
        <div class="result-header">
          <h4>📊 审计结果</h4>
        </div>
        
        <div v-if="auditResult" class="audit-result">
          <div class="result-summary">
            <div class="summary-item">
              <span class="label">漏洞数量:</span>
              <span class="value critical">{{ auditResult.vulnerabilities.length }}</span>
            </div>
            <div class="summary-item">
              <span class="label">风险等级:</span>
              <span class="value" :class="getRiskLevelClass(auditResult.riskLevel)">
                {{ auditResult.riskLevel }}
              </span>
            </div>
          </div>
          
          <!-- 显示摘要 -->
          <div v-if="auditResult.summary" class="audit-summary">
            <h6>审计摘要</h6>
            <p>{{ auditResult.summary }}</p>
          </div>
          
          <div v-if="auditResult.vulnerabilities.length > 0" class="vulnerabilities">
            <h6>发现的安全问题:</h6>
            <div 
              v-for="(vuln, index) in auditResult.vulnerabilities" 
              :key="index" 
              class="vulnerability-item"
            >
              <div class="vuln-header">
                <span class="vuln-type" :class="vuln.severity.toLowerCase()">{{ vuln.title }}</span>
                <span class="vuln-severity">{{ vuln.severity }}</span>
                <span class="vuln-swc" v-if="vuln.swcId">SWC-{{ vuln.swcId }}</span>
              </div>
              <div class="vuln-description">{{ vuln.description }}</div>
              <div class="vuln-location" v-if="vuln.evidence && vuln.evidence.lines">
                位置: 第{{ vuln.evidence.lines.join(', ') }}行
              </div>
              <div class="vuln-suggestion">建议: {{ vuln.recommendation }}</div>
              <div class="vuln-confidence" v-if="vuln.confidence">
                置信度: {{ Math.round(vuln.confidence * 100) }}%
              </div>
            </div>
          </div>
          
          <div v-else-if="!auditResult.error" class="no-vulnerabilities">
            <div class="success-icon">✅</div>
            <p>未发现明显的安全漏洞</p>
          </div>
          
          <!-- 错误状态 -->
          <div v-if="auditResult.error" class="error-state">
            <div class="error-icon">❌</div>
            <p>{{ auditResult.summary }}</p>
          </div>
          
          <!-- 报告操作 -->
          <div class="report-actions">
            <button class="btn primary" @click="copyReport">复制报告</button>
            <button class="btn secondary" @click="downloadReport">下载报告</button>
          </div>
        </div>
        
        <div v-if="auditResult.rawReport" class="raw-report-view" style="margin-top:16px">
          <h6>原始报告输出：</h6>
          <pre style="background:#f8f8f8;color:#444;font-size:12px;padding:8px;border-radius:4px;white-space:pre-wrap;overflow-x:auto;">{{ auditResult.rawReport }}</pre>
        </div>
        
        <div v-else-if="auditing" class="auditing-indicator">
          <div class="spinner"></div>
          <span>AI正在分析智能合约，请稍候...</span>
        </div>
        
        <div v-else class="no-result">
          <div class="placeholder-icon">📋</div>
          <p>请输入合约代码并开始审计</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
import { API_BASE_URL } from '@/config/api';

// Props 定义
interface Props {
  testMode?: boolean;
  testData?: any;
}

const props = withDefaults(defineProps<Props>(), {
  testMode: false,
  testData: null
});

const contractCode = ref('');
const auditDepth = ref(3);
const auditMode = ref('standard');
const auditing = ref(false);
const auditResult = ref<any>(null);

// 示例代码
const vulnerableExample = `pragma solidity ^0.8.0;

contract VulnerableContract {
    mapping(address => uint256) public balances;
    
    function withdraw(uint256 amount) public {
        require(balances[msg.sender] >= amount);
        
        // 重入攻击漏洞
        msg.sender.call{value: amount}("");
        
        balances[msg.sender] -= amount;
    }
    
    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }
}`;

const safeExample = `pragma solidity ^0.8.0;

contract SafeContract {
    mapping(address => uint256) public balances;
    mapping(address => bool) public locked;
    
    modifier noReentrancy() {
        require(!locked[msg.sender], "Reentrancy detected");
        locked[msg.sender] = true;
        _;
        locked[msg.sender] = false;
    }
    
    function withdraw(uint256 amount) public noReentrancy {
        require(balances[msg.sender] >= amount, "Insufficient balance");
        
        balances[msg.sender] -= amount;
        
        (bool success, ) = msg.sender.call{value: amount}("");
        require(success, "Transfer failed");
    }
    
    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }
}`;

const loadVulnerableExample = () => {
  contractCode.value = vulnerableExample;
};

const loadSafeExample = () => {
  contractCode.value = safeExample;
};

const clearCode = () => {
  contractCode.value = '';
  auditResult.value = null;
};

const startAudit = async () => {
  if (!contractCode.value.trim()) return;
  
  auditing.value = true;
  auditResult.value = null;
  
  try {
    const response = await fetch(`${API_BASE_URL}/api/contract/analyze`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        source_code: contractCode.value,
      }),
    });
    
    if (response.ok) {
      const result = await response.json();
      
      if (result.success && result.data) {
        // 处理后端返回的数据格式
        const data = result.data;
        auditResult.value = {
          vulnerabilities: data.findings || [],
          riskLevel: getRiskLevelFromFindings(data.findings || []),
          auditTime: data.timestamp || new Date().toISOString(),
          summary: data.summary || '',
          reportMarkdown: data.report_markdown || '',
          rawReport: data.report || ''
        };
      } else {
        throw new Error(result.error || '审计失败');
      }
    } else {
      const errorData = await response.json();
      throw new Error(errorData.error || `HTTP ${response.status}`);
    }
  } catch (error) {
    console.error('审计请求失败:', error);
    // 显示错误信息
    auditResult.value = {
      vulnerabilities: [],
      riskLevel: '错误',
      auditTime: new Date().toISOString(),
      summary: `审计失败: ${error.message}`,
      reportMarkdown: '',
      error: true,
      rawReport: '' // 添加 rawReport 字段
    };
  } finally {
    auditing.value = false;
  }
};

// 根据发现的问题计算风险等级
const getRiskLevelFromFindings = (findings: any[]) => {
  if (!findings || findings.length === 0) return '安全';
  
  const highSeverity = findings.filter(f => f.severity === 'High').length;
  const mediumSeverity = findings.filter(f => f.severity === 'Medium').length;
  
  if (highSeverity > 0) return '高风险';
  if (mediumSeverity > 0) return '中风险';
  return '低风险';
};

const getRiskLevelClass = (level: string) => {
  switch (level) {
    case '高风险': return 'critical';
    case '中风险': return 'warning';
    case '低风险': return 'info';
    case '安全': return 'safe';
    case '错误': return 'error';
    default: return 'safe';
  }
};

const copyReport = () => {
  if (!auditResult.value) return;
  
  const report = generateReportText();
  navigator.clipboard.writeText(report).then(() => {
    alert('报告已复制到剪贴板');
  });
};

const downloadReport = () => {
  if (!auditResult.value) return;
  
  const report = generateReportText();
  const blob = new Blob([report], { type: 'text/plain;charset=utf-8' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `合约审计报告_${new Date().toISOString().split('T')[0]}.txt`;
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url);
};

const generateReportText = () => {
  if (!auditResult.value) return '';
  
  let report = `智能合约安全审计报告\n`;
  report += `审计时间: ${auditResult.value.auditTime}\n`;
  report += `风险等级: ${auditResult.value.riskLevel}\n\n`;
  
  if (auditResult.value.summary) {
    report += `审计摘要:\n${auditResult.value.summary}\n\n`;
  }
  
  if (auditResult.value.vulnerabilities.length > 0) {
    report += `发现的安全问题:\n`;
    auditResult.value.vulnerabilities.forEach((vuln: any, index: number) => {
      report += `${index + 1}. ${vuln.title} (${vuln.severity})\n`;
      if (vuln.swcId) {
        report += `   SWC编号: SWC-${vuln.swcId}\n`;
      }
      report += `   描述: ${vuln.description}\n`;
      if (vuln.evidence && vuln.evidence.lines) {
        report += `   位置: 第${vuln.evidence.lines.join(', ')}行\n`;
      }
      report += `   建议: ${vuln.recommendation}\n`;
      if (vuln.confidence) {
        report += `   置信度: ${Math.round(vuln.confidence * 100)}%\n`;
      }
      report += `\n`;
    });
  } else if (!auditResult.value.error) {
    report += `未发现明显的安全漏洞。\n`;
  } else {
    report += `审计过程中发生错误: ${auditResult.value.summary}\n`;
  }
  
  return report;
};

// 测试模式：监听 testData 变化并更新组件状态
watch(() => props.testData, (newData) => {
  if (props.testMode && newData) {
    if (newData.loading) {
      auditing.value = true;
      auditResult.value = null;
    } else if (newData.success === false) {
      auditing.value = false;
      auditResult.value = {
        vulnerabilities: [],
        riskLevel: '错误',
        auditTime: new Date().toISOString(),
        summary: newData.error || '测试错误',
        reportMarkdown: '',
        error: true,
        rawReport: ''
      };
    } else {
      auditing.value = false;
      auditResult.value = {
        vulnerabilities: newData.data?.findings || [],
        riskLevel: getRiskLevelFromFindings(newData.data?.findings || []),
        auditTime: newData.timestamp || new Date().toISOString(),
        summary: newData.data?.summary || '',
        reportMarkdown: newData.data?.report_markdown || '',
        rawReport: newData.data?.analysis || newData.data?.report || ''
      };
    }
  }
}, { immediate: true });
</script>

<style scoped>
.regulation-panel {
  height: 100%;
  background: var(--card);
  display: flex;
  flex-direction: column;
}

.panel-header {
  padding: 16px;
  border-bottom: 1px solid var(--border);
  background: var(--muted);
}

.panel-header h3 {
  margin: 0 0 4px 0;
  font-size: 16px;
  color: var(--primary);
}

.panel-subtitle {
  margin: 0;
  font-size: 12px;
  color: var(--muted-foreground);
}

.panel-content {
  flex: 1;
  display: flex;
  overflow: hidden;
}

.left-section {
  width: 45%;
  padding: 16px;
  border-right: 1px solid var(--border);
  overflow-y: auto;
}

.right-section {
  width: 55%;
  padding: 16px;
  overflow-y: auto;
}

.result-header {
  margin-bottom: 16px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}

.result-header h4 {
  margin: 0;
  font-size: 14px;
  color: var(--foreground);
}

.code-upload-section {
  margin-bottom: 16px;
}

.code-upload-section h4 {
  margin: 0 0 8px 0;
  font-size: 14px;
  color: var(--foreground);
}

.code-input-area {
  margin-bottom: 8px;
}

.code-textarea {
  width: 100%;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--background);
  color: var(--foreground);
  font-family: 'Courier New', monospace;
  font-size: 12px;
  resize: vertical;
  min-height: 120px;
}

.example-buttons {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}

.audit-params {
  margin-bottom: 16px;
  padding: 12px;
  background: var(--muted);
  border-radius: 4px;
}

.audit-params h5 {
  margin: 0 0 8px 0;
  font-size: 12px;
  color: var(--foreground);
}

.param-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.param-row label {
  font-size: 11px;
  color: var(--muted-foreground);
  min-width: 80px;
}

.slider {
  flex: 1;
  height: 4px;
  background: var(--border);
  border-radius: 2px;
  outline: none;
}

.mode-select {
  flex: 1;
  padding: 4px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--background);
  color: var(--foreground);
  font-size: 11px;
}

.action-buttons {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
}

.audit-btn {
  flex: 1;
}

.audit-result {
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 12px;
  background: var(--background);
}

.audit-result h5 {
  margin: 0 0 8px 0;
  font-size: 14px;
  color: var(--foreground);
}

.result-summary {
  display: flex;
  gap: 16px;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}

.summary-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.summary-item .label {
  font-size: 11px;
  color: var(--muted-foreground);
}

.summary-item .value {
  font-size: 14px;
  font-weight: 600;
}

.value.critical {
  color: #ef4444;
}

.value.warning {
  color: #f59e0b;
}

.value.info {
  color: #3b82f6;
}

.value.safe {
  color: #10b981;
}

.value.error {
  color: #ef4444;
}

.audit-summary {
  margin-bottom: 12px;
  padding: 8px;
  background: var(--muted);
  border-radius: 4px;
}

.audit-summary h6 {
  margin: 0 0 4px 0;
  font-size: 12px;
  color: var(--foreground);
}

.audit-summary p {
  margin: 0;
  font-size: 11px;
  color: var(--muted-foreground);
  line-height: 1.4;
}

.error-state {
  text-align: center;
  padding: 20px;
  color: #ef4444;
}

.error-icon {
  font-size: 24px;
  margin-bottom: 8px;
}

.vuln-swc {
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 2px;
  background: var(--background);
  color: var(--muted-foreground);
  margin-left: 8px;
}

.vuln-confidence {
  font-size: 10px;
  color: var(--muted-foreground);
  margin-top: 2px;
}

.vulnerabilities h6 {
  margin: 0 0 8px 0;
  font-size: 12px;
  color: var(--foreground);
}

.vulnerability-item {
  margin-bottom: 12px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--muted);
}

.vuln-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 4px;
}

.vuln-type {
  font-size: 12px;
  font-weight: 600;
}

.vuln-type.high {
  color: #ef4444;
}

.vuln-type.medium {
  color: #f59e0b;
}

.vuln-type.low {
  color: #3b82f6;
}

.vuln-severity {
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 2px;
  background: var(--background);
  color: var(--foreground);
}

.vuln-description,
.vuln-location,
.vuln-suggestion {
  font-size: 11px;
  color: var(--muted-foreground);
  margin-bottom: 2px;
}

.no-vulnerabilities {
  text-align: center;
  padding: 20px;
  color: var(--muted-foreground);
}

.success-icon {
  font-size: 24px;
  margin-bottom: 8px;
}

.report-actions {
  display: flex;
  gap: 8px;
  margin-top: 12px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}

.btn {
  padding: 6px 12px;
  border-radius: 4px;
  border: 1px solid transparent;
  cursor: pointer;
  font-size: 11px;
  transition: all 0.2s ease;
}

.btn.primary {
  background: var(--primary);
  color: white;
}

.btn.primary:hover:not(:disabled) {
  background: var(--primary);
  opacity: 0.9;
}

.btn.primary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn.secondary {
  background: var(--background);
  border-color: var(--border);
  color: var(--foreground);
}

.btn.secondary:hover {
  background: var(--muted);
}

.auditing-indicator {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 20px;
  color: var(--muted-foreground);
  font-size: 14px;
}

.spinner {
  width: 16px;
  height: 16px;
  border: 2px solid var(--border);
  border-top: 2px solid var(--primary);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.no-result {
  text-align: center;
  padding: 40px 20px;
  color: var(--muted-foreground);
}

.placeholder-icon {
  font-size: 32px;
  margin-bottom: 12px;
}

.raw-report-view {
  margin-top: 16px;
  padding: 8px;
  background: var(--muted);
  border: 1px solid var(--border);
  border-radius: 4px;
  overflow-x: auto;
}

.raw-report-view h6 {
  margin: 0 0 4px 0;
  font-size: 12px;
  color: var(--foreground);
}

.raw-report-view pre {
  white-space: pre-wrap; /* 允许文本换行 */
  word-wrap: break-word; /* 允许长单词换行 */
  font-family: 'Courier New', monospace;
  font-size: 12px;
  color: #444;
  background: #f8f8f8;
  padding: 8px;
  border-radius: 4px;
}
</style>
